using System;
using System.Collections.Generic;
using System.ComponentModel.DataAnnotations;
using System.ComponentModel.DataAnnotations.Schema;
using WalkingTec.Mvvm.Core;
using WalkingTec.Mvvm.Core.Attributes;

namespace HengTong.Model.Db.Hr.Attendance;

/// <summary>
/// 考勤班组实体类，用于管理不同类型的班次组合和排班模式
/// </summary>
/// <remarks>
/// 包含班组基本信息、排班类型配置、排班模式设置等功能。
/// 支持行政班、三班倒、两班倒等多种排班类型的管理，
/// 通过班组可以对多个班次进行统一管理和调度
/// </remarks>
public class SysAttendanceShiftGroup : TopBasePoco
{
    /// <summary>
    /// 获取或设置班组名称
    /// </summary>
    /// <value>班组的显示名称，用于标识不同的考勤班组</value>
    [Display(Name = "班组名称", Description = "考勤班组的显示名称，用于区分不同的班组", GroupName = "基本信息")]
    [Required(ErrorMessage = "班组名称不能为空")]
    [StringLength(32, ErrorMessage = "班组名称长度不能超过32个字符")]
    public string Name { get; set; }

    /// <summary>
    /// 获取或设置班组描述信息
    /// </summary>
    /// <value>对班组的详细说明，包括适用范围、特殊要求等</value>
    [Display(Name = "班组描述", Description = "班组的详细描述信息，说明班组的用途和特点", GroupName = "基本信息")]
    [StringLength(256, ErrorMessage = "班组描述长度不能超过256个字符")]
    public string Description { get; set; }

    /// <summary>
    /// 获取或设置班组的排班类型
    /// </summary>
    /// <value>班组的排班模式：行政班、三班倒或两班倒</value>
    [Display(Name = "排班类型", Description = "班组的排班模式（行政班/三班倒/两班倒）", GroupName = "排班设置")]
    [Required(ErrorMessage = "排班类型不能为空")]
    public ShiftGroupType? Type { get; set; }

    /// <summary>
    /// 获取或设置班组的排班模式配置
    /// </summary>
    /// <value>行政班存储工作日配置；其他班次存储当天班次模板，用于据此计算工作日</value>
    [Display(Name = "排班模式", Description = "排班模式配置：行政班存储工作日，班倒模式存储班次模板", GroupName = "排班设置")]
    [StringLength(512, ErrorMessage = "排班模式配置长度不能超过512个字符")]
    public string SchedulePattern { get; set; }

    // —— 工时折算 ——

    /// <summary>
    /// 获取或设置标准工作时长(月)
    /// </summary>
    /// <value>班组的月度标准工作时长,单位为分钟</value>
    [Display(Name = "标准工作时长(分钟/月)", Description = "班组的月度标准工作时长", GroupName = "工时折算")]
    [Range(0, 1000000, ErrorMessage = "标准工作时长必须在0-1000000分钟之间")]
    public int StandardWorkMinutes { get; set; } = 10080; // 21天 * 8小时 * 60分钟 = 10080分钟

    /// <summary>
    /// 获取或设置工时折算出勤天数(月)
    /// </summary>
    /// <value>完成月度标准工时对应的出勤天数,用于计算出勤率</value>
    [Display(Name = "折算出勤天数(月)", Description = "完成月度标准工时对应的出勤天数", GroupName = "工时折算")]
    [Range(typeof(decimal), "0", "31", ErrorMessage = "折算出勤天数必须在0-31之间")]
    [Column(TypeName = "decimal(4,2)")]
    public decimal? AttendanceDays { get; set; } = 21m; // 按照每月21个工作日计算

    /// <summary>
    /// 获取或设置班组包含的班次列表
    /// </summary>
    /// <value>该班组下所有可用的考勤班次</value>
    [Display(Name = "班次列表", Description = "该班组下包含的所有考勤班次", GroupName = "班次管理")]
    public List<SysAttendanceShiftAndGroup> Shifts { get; set; }
    
    [Display(Name = "排序")]
    [Column(TypeName = "decimal(4,2)")]
    [Range(0, 99.99, ErrorMessage = "排序值必须在0到99.99之间")]
    [DisplayFormat(DataFormatString = "{0:0.##}")]
    public decimal? Order { get; set; } = 0;
}

/// <summary>
/// 班组排班类型枚举
/// </summary>
/// <remarks>
/// 定义了不同的班组排班模式，支持常见的企业排班需求
/// </remarks>
public enum ShiftGroupType
{
    /// <summary>
    /// 行政班（固定工作日的常规班次）
    /// </summary>
    [Display(Name = "行政班", Description = "固定工作日的常规办公班次")]
    行政班,

    /// <summary>
    /// 三班倒（12小时三班轮换制）
    /// </summary>
    [Display(Name = "三班倒", Description = "12小时轮换的三班制")]
    三班倒,

    /// <summary>
    /// 两班倒（24小时两班轮换制）
    /// </summary>
    [Display(Name = "两班倒", Description = "24小时轮换的两班制")]
    两班倒,

    /// <summary>
    /// 上一休二（工作1天休息2天的轮换制）
    /// </summary>
    [Display(Name = "上一休二", Description = "工作1天休息2天的轮换制")]
    上一休二
}

[MiddleTable]
public class SysAttendanceShiftAndGroup : TopBasePoco
{
    /// <summary>
    /// 获取或设置班次ID
    /// </summary>
    /// <value>关联的班次ID</value>
    [Display(Name = "班次", Description = "关联的班次", GroupName = "基本信息")]
    [Required(ErrorMessage = "班次不能为空")]
    public Guid? ShiftId { get; set; }

    /// <summary>
    /// 获取或设置班次导航属性
    /// </summary>
    /// <value>关联的班次实体</value>
    public SysAttendanceShift Shift { get; set; }

    /// <summary>
    /// 获取或设置班组ID
    /// </summary>
    /// <value>关联的班组ID</value>
    [Display(Name = "班组", Description = "关联的班组", GroupName = "基本信息")]
    [Required(ErrorMessage = "班组不能为空")]
    public Guid? GroupId { get; set; }

    /// <summary>
    /// 获取或设置班组导航属性
    /// </summary>
    /// <value>关联的班组实体</value>
    public SysAttendanceShiftGroup Group { get; set; }
        
    /// <summary>
    /// 获取或设置标签类型
    /// </summary>
    /// <value>分类标签：A、中班或夜班</value>
    [Display(Name = "标签", Description = "类型标签（A/B/C）", GroupName = "基本信息")]
    public SysAttendanceShiftTag? Tag { get; set; }
    
}